package main

import "fmt"

//全局变量
var (
	arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
)

func main() {
	//slice1()
	//slice2(arr[2:])
	//printArr()
	//slice()
	//slice3()
	//sliceTest()
	//sliceCopy()
	testMap()
}

func testMap() {
	m := make(map[string]int)
	m["a"] = 2
	x, ok := m["b"]
	if ok {
		fmt.Println(x)
	} else {
		fmt.Println("map not exists key and value")
	}
}

/*
	slice是对整个数组的view(相当于表和视图的关系，视图改变的是表的内容)
*/
func slice1() {
	arr := [...]int{1, 2, 3, 4, 5, 6, 7}
	fmt.Println("arr[2:6] = ", arr[2:6])
	fmt.Println("arr[:6] = ", arr[:6])
	fmt.Println("arr[2:] = ", arr[2:])
	fmt.Println("arr[:] = ", arr[:])
}

/*
Slice本身没有数据，是对底层array的一个view
arr的值变为[0 1 10 3 4 5 6 7]
slice可以向后扩展，不可以向前扩展
s[i]不可以i超越Len(s)，向后扩展不能超越底层数组cap(s)
添加元素时如果超越cap，系统会重新分配更大的底层数组
*/
func slice2(arr []int) {
	arr[0] = 10
}

func printArr() {
	fmt.Println(arr)
}

func slice() {
	var s []int //Zero value for slice is nil
	for i := 0; i < 100; i++ {
		s = append(s, 2*i+1)
	}
	fmt.Println(s)
}

func slice3() {
	s1 := []int{1, 2, 3, 4, 5}
	s2 := make([]int, 16)
	s3 := make([]int, 10, 32)
	fmt.Printf("s1 's size: %d , s1 's cap : %d\n", len(s1), cap(s1))
	fmt.Printf("s2 's size: %d , s2 's cap : %d\n", len(s2), cap(s2))
	fmt.Printf("s3 's size: %d , s3 's cap : %d\n", len(s3), cap(s3))

	// copy slice from another slice
	copy(s2, s1)
	fmt.Println(s2)

	//delete elements from slice
	s2 = append(s2[3:], s2[4:]...)
	fmt.Println(s2)

	// poping from front
	front := s2[0]
	s2 = s2[1:]

	tail := s2[len(s2)-1]
	s2 = s2[:len(s2)-1]
	fmt.Println(front, tail)
	fmt.Println(s2)
}

func sliceTest() {
	s1 := make([]int, 0, 5)
	fmt.Printf("%p\n", &s1)
	s2 := append(s1, 1)
	fmt.Printf("%p\n", &s2)
	fmt.Println(s1, s2)
	fmt.Printf("s1的len: %d,s1的cap: %d \n", len(s1), cap(s1))
	fmt.Printf("s2的len: %d,s2的cap: %d \n", len(s2), cap(s1))
	// 数组初始化的方法 [...]int{a,b,c,d,index:data} a,b,c为前边的值，index为索引为index的值设置为data
	ss := [...]int{1, 2, 3, 4, 5, 6, 6: 7}
	fmt.Println(ss)
	//:2 表示是ss的前两个元素，并且指定slice的cap为7，但是cap的值不能超过原来数组的长度
	slicet := ss[:2:7]
	fmt.Println(slicet)
}

func sliceCopy() {
	s1 := []int{1, 2, 3, 4, 5}
	fmt.Printf("slice s1 : %v\n", s1)
	fmt.Printf("ptr slice s1 : %p\n", &s1)
	s2 := make([]int, 10)
	fmt.Printf("slice s2 : %v\n", s2)
	fmt.Printf("ptr slice s2 : %p\n", &s2)
	copy(s2, s1)
	fmt.Printf("copied slice s1 : %v\n", s1)
	fmt.Printf("ptr copied slice s1 : %p\n", &s1)
	fmt.Printf("copied slice s2 : %v\n", s2)
	fmt.Printf("ptr copied slice s2 : %p\n", &s2)
	s3 := []int{1, 2, 3}
	fmt.Printf("slice s3 : %v\n", s3)
	fmt.Printf("ptr slice s3: %p\n", &s3)
	fmt.Printf("s3 len is : %d\n", len(s3))
	s3 = append(s3, s2...)
	fmt.Printf("appended slice s3 : %v\n", s3)
	fmt.Printf("ptr appended slice s3: %p\n", &s3)
	fmt.Printf("appended s3 len is : %d\n", len(s3))
	s3 = append(s3, 4, 5, 6)
	fmt.Printf("last slice s3 : %v\n", s3)
}
